package com.ruoyi.ftrl.server;

import org.tio.core.ChannelContext;


import org.tio.core.Tio;
import org.tio.core.TioConfig;
import org.tio.core.exception.TioDecodeException;
import org.tio.core.intf.Packet;

import org.tio.server.intf.TioServerHandler;

import java.nio.ByteBuffer;

public class MyServerAioHandler implements TioServerHandler {
    /**
     * 解码 首先把接受到的bytebuffer解码成可以识别的业务包
     * 消息结构 消息头+消息体
     * 消息头:6个字节
     * 消息体:json串的byte[]
     * @param
     * @param channelContext
     * @return
     * @throws
     */
    @Override
    public Packet decode(ByteBuffer buffer, int limit, int position, int readableLength, ChannelContext channelContext) throws TioDecodeException {
        //收到的数据组不成业务包,则返回null告诉框架数据不够
        if (readableLength< HelloPacket.HEADER_LENGHT){
            return null;
        }
        //获取消息体长度
        int bodyLength=buffer.getInt();
        //消息体长度不正确
        if (bodyLength<0){
            throw new TioDecodeException("bodyLength与"+channelContext.getClientNode()+"不准确");
        }
        //计算本次需要的数据长度
        int neededLength =HelloPacket.HEADER_LENGHT+bodyLength;
        //收到的数据是否足够组包
        int isDataEnough=readableLength-neededLength;
        if (isDataEnough<0){
            return null;
        }else {
            HelloPacket imPacket = new HelloPacket();
            if (bodyLength>0){
                byte[] dst =new byte[bodyLength];
                buffer.get(dst);
                imPacket.setBody(dst);
            }
            return imPacket;
        }

    }

    /**
     * 编码：把业务消息包编码为可以发送的ByteBuffer
     * 总的消息结构：消息头 + 消息体
     * 消息头结构：    6个字节，存储消息体的长度
     * 消息体结构：   对象的json串的byte[]
     */
    @Override
    public ByteBuffer encode(Packet packet, TioConfig tioConfig, ChannelContext channelContext) {
        HelloPacket helloPacket=new HelloPacket();
        byte[] body=helloPacket.getBody();
        int bodyLen=0;
        if (body!=null){
            bodyLen=body.length;
        }
        //bytebuffer的总长度是 = 消息头的长度 + 消息体的长度
        int allLen = HelloPacket.HEADER_LENGHT + bodyLen;
        //创建一个新的byteBuffer
        ByteBuffer buffer=ByteBuffer.allocate(allLen);
        buffer.order(tioConfig.getByteOrder());

        //写入消息头----消息头的长度
        buffer.putInt(bodyLen);

        if (body!=null){
            buffer.put(body);
        }
        return buffer;
    }

    /**
     * 处理消息
     * @param packet
     * @param channelContext
     * @throws Exception
     */
    @Override
    public void handler(Packet packet, ChannelContext channelContext) throws Exception {
        //收到消息 强转成自己的packet
        HelloPacket helloPacket = (HelloPacket) packet;
        //消息体
        byte[] body = helloPacket.getBody();
        if (body != null) {
            String str = new String(body, HelloPacket.CHARSET);
            System.out.println("收到消息：" + str);

            HelloPacket resppacket = new HelloPacket();
            resppacket.setBody(("收到了你的消息，你的消息是:" + str).getBytes(HelloPacket.CHARSET));
            Tio.send(channelContext, resppacket);
        }

    }


}
